package org.baojie;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 数据库类型
 *
 * @author haqiaolong 2016年3月8日 下午1:24:13
 * @since 5.0.0
 */
public enum DataBaseType {

    MySql("1", "mysql", "com.mysql.jdbc.Driver"),
    DRDS("2", "drds", "com.mysql.jdbc.Driver"),
    Oracle("3", "oracle", "oracle.jdbc.OracleDriver"),
    SQLSERVER("4", "sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver"),
    ROCKETMQ("5", "rocketmq", "rocketmq"),
    Mongo("6", "mongo", "mongo");
    private String typeName;
    private String driverClassName;
    private String typeFullName;

    DataBaseType(String typeName, String typeFullName, String driverClassName) {
        this.typeName = typeName;
        this.driverClassName = driverClassName;
        this.typeFullName = typeFullName;
    }

    public static DataBaseType getDataBaseType(String type) {
        for (DataBaseType reader : DataBaseType.values()) {
            if (reader.getTypeName().equals(type) || reader.getTypeFullName().equals(type)) {
                return reader;
            }
        }
        return null;
    }

    public String getDriverClassName() {
        return this.driverClassName;
    }

    public String getTypeFullName() {
        return typeFullName;
    }

    public String appendJDBCSuffixForReader(String jdbc) throws Throwable {
        String result = jdbc;
        String suffix = null;
        switch (this) {
            case MySql:
            case DRDS:
                suffix = "yearIsDateType=false&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false&rewriteBatchedStatements=true";
                if (jdbc.contains("?")) {
                    result = jdbc + "&" + suffix;
                } else {
                    result = jdbc + "?" + suffix;
                }
                break;
            case Oracle:
                break;
            default:
                throw new Throwable("unsupported database type.");
        }

        return result;
    }

    public String appendJDBCSuffixForWriter(String jdbc) throws Throwable {
        String result = jdbc;
        String suffix = null;
        switch (this) {
            case MySql:
                suffix = "yearIsDateType=false&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true&tinyInt1isBit=false";
                if (jdbc.contains("?")) {
                    result = jdbc + "&" + suffix;
                } else {
                    result = jdbc + "?" + suffix;
                }
                break;
            case DRDS:
                suffix = "yearIsDateType=false&zeroDateTimeBehavior=convertToNull";
                if (jdbc.contains("?")) {
                    result = jdbc + "&" + suffix;
                } else {
                    result = jdbc + "?" + suffix;
                }
                break;
            case Oracle:
                break;
            default:
                throw new Throwable("unsupported database type.");
        }

        return result;
    }

    public String formatPk(String splitPk) throws Throwable {
        String result = splitPk;

        switch (this) {
            case MySql:
            case Oracle:
                if (splitPk.length() >= 2 && splitPk.startsWith("`") && splitPk.endsWith("`")) {
                    result = splitPk.substring(1, splitPk.length() - 1).toLowerCase();
                }
                break;
            default:
                throw new Throwable("unsupported database type.");
        }

        return result;
    }

    public String quoteColumnName(String columnName) throws Throwable {
        String result = columnName;

        switch (this) {
            case MySql:
                result = "`" + columnName.replace("`", "``") + "`";
                break;
            case Oracle:
                break;
            default:
                throw new Throwable("unsupported database type.");
        }

        return result;
    }

    public String quoteTableName(String tableName) throws Throwable {
        String result = tableName;

        switch (this) {
            case MySql:
                result = "`" + tableName.replace("`", "``") + "`";
                break;
            case Oracle:
                break;
            default:
                throw new Throwable("unsupported database type.");
        }

        return result;
    }

    private static Pattern mysqlPattern = Pattern.compile("jdbc:mysql://(.+):\\d+/.+");
    private static Pattern oraclePattern = Pattern.compile("jdbc:oracle:thin:@(.+):\\d+:.+");

    /**
     * 注意：目前只实现了从 mysql/oracle 中识别出ip 信息.未识别到则返回 null.
     */
    public static String parseIpFromJdbcUrl(String jdbcUrl) {
        Matcher mysql = mysqlPattern.matcher(jdbcUrl);
        if (mysql.matches()) {
            return mysql.group(1);
        }
        Matcher oracle = oraclePattern.matcher(jdbcUrl);
        if (oracle.matches()) {
            return oracle.group(1);
        }
        return null;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    public boolean isOracle() {
        return this.equals(Oracle);
    }


    public boolean isMysql() {
        return this.equals(MySql);
    }

    public boolean isDRDS() {
        return this.equals(DRDS);
    }

    public boolean isMongo() {
        return this.equals(Mongo);
    }

    public DataBaseType parse(Integer code) {
        switch (code) {
            case 1:
                return MySql;
            case 2:
                return DRDS;
            case 3:
                return Oracle;
            case 6:
                return Mongo;
            default:
                return null;
        }
    }

}
